package com.open4cn.simulator.core.connector.serialport;

import cn.hutool.core.io.IoUtil;
import gnu.io.SerialPort;
import gnu.io.SerialPortEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.TooManyListenersException;

/**
 * @author yinxiaopeng
 * @version 1.0.0
 * @company 致景科技
 * @department 飞梭BU/研发
 * @description
 * @Email yinxiaopeng@zj.tech
 * @date 2022-06-11 19:18
 */
public class SerialPortChannel implements Serializable {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private SerialPort serialPort;

    public SerialPortChannel(SerialPort serialPort) {
        this.serialPort = serialPort;
    }


    public void addEventListener(SerialPortEventListener listener) {
        if (null != serialPort) {
            try {
                serialPort.addEventListener(listener);
            } catch (TooManyListenersException e) {
                logger.error("{}串口监听类对象过多", getName(), e);
            }
        }
    }


    /**
     * 从串口读取数据
     *
     * @return
     */
    public byte[] read() {
        if (null != serialPort) {
            InputStream input = null;
            try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
                input = serialPort.getInputStream();
                byte[] buffer = new byte[1024];
                int count;
                while ((count = input.read(buffer)) > 0) {
                    output.write(buffer, 0, count);
                }
                return output.toByteArray();
            } catch (IOException e) {
                logger.error("{}串口读取数据异常", getName(), e);
            } finally {
                try {
                    if (input != null) {
                        input.close();
                    }
                } catch (IOException e) {
                }
            }
        }
        return new byte[0];
    }

    /**
     * 向串口写入数据
     *
     * @param bytes
     */
    public void write(byte[] bytes) {
        if (null != serialPort) {
            OutputStream out = null;
            try {
                out = serialPort.getOutputStream();
                out.write(bytes);
                out.flush();
            } catch (IOException e) {
                logger.error("{}串口发送数据异常", getName(), e);
            } finally {
                IoUtil.close(out);
            }
        }
    }

    public String getName() {
        if (null != serialPort) {
            return serialPort.getName();
        }
        return null;
    }

    /**
     * 关闭
     */
    public void close() {
        if (null != serialPort) {
            serialPort.close();
        }
    }
}
